use crate::{AppError, AppResult, Call, CallStatus, SipRegister, RegisterStatus};
use chrono::Utc;
use std::collections::HashMap;
use std::sync::Mutex;
use uuid::Uuid;

// 内存中的SIP数据存储
lazy_static::lazy_static! {
    static ref CALLS: Mutex<HashMap<String, Call>> = Mutex::new(HashMap::new());
    static ref REGISTERS: Mutex<HashMap<String, SipRegister>> = Mutex::new(HashMap::new());
}

pub struct SipService;

impl SipService {
    // 初始化示例数据
    pub fn init_sample_data() {
        let mut calls = CALLS.lock().unwrap();
        let mut registers = REGISTERS.lock().unwrap();

        // 添加示例通话记录
        let sample_call = Call {
            id: "call_001".to_string(),
            caller: "1001".to_string(),
            callee: "1002".to_string(),
            status: CallStatus::Ended,
            start_time: Utc::now() - chrono::Duration::minutes(30),
            end_time: Some(Utc::now() - chrono::Duration::minutes(25)),
            duration: Some(300), // 5分钟
            recording_path: Some("/recordings/call_001.wav".to_string()),
            sip_server: "192.168.1.100".to_string(),
            call_id: "call_001".to_string(),
        };
        calls.insert("call_001".to_string(), sample_call);

        // 添加示例注册记录
        let sample_register = SipRegister {
            id: "reg_001".to_string(),
            username: "1001".to_string(),
            domain: "example.com".to_string(),
            password: "password123".to_string(),
            status: RegisterStatus::Registered,
            register_time: Some(Utc::now() - chrono::Duration::hours(2)),
            expire_time: Some(Utc::now() + chrono::Duration::hours(22)),
            last_heartbeat: Some(Utc::now() - chrono::Duration::minutes(5)),
            sip_server: "192.168.1.100".to_string(),
            port: 5060,
        };
        registers.insert("reg_001".to_string(), sample_register);
    }

    // 获取通话列表
    pub fn get_calls() -> Vec<Call> {
        let calls = CALLS.lock().unwrap();
        calls.values().cloned().collect()
    }

    // 创建新通话
    pub fn create_call(caller: String, callee: String, sip_server: String) -> AppResult<Call> {
        let mut calls = CALLS.lock().unwrap();
        
        let call = Call {
            id: Uuid::new_v4().to_string(),
            caller,
            callee,
            status: CallStatus::Ringing,
            start_time: Utc::now(),
            end_time: None,
            duration: None,
            recording_path: None,
            sip_server,
            call_id: Uuid::new_v4().to_string(),
        };

        calls.insert(call.id.clone(), call.clone());
        Ok(call)
    }

    // 更新通话状态
    pub fn update_call_status(call_id: &str, status: CallStatus) -> AppResult<()> {
        let mut calls = CALLS.lock().unwrap();
        
        if let Some(call) = calls.get_mut(call_id) {
            call.status = status.clone();
            
            match status {
                CallStatus::Ended | CallStatus::Failed => {
                    call.end_time = Some(Utc::now());
                    if let Some(start_time) = Some(call.start_time) {
                        call.duration = Some((Utc::now() - start_time).num_seconds());
                    }
                }
                _ => {}
            }
            Ok(())
        } else {
            Err(AppError::NotFoundError("通话不存在".to_string()))
        }
    }

    // 挂断通话
    pub fn hangup_call(call_id: &str) -> AppResult<()> {
        Self::update_call_status(call_id, CallStatus::Ended)
    }

    // 获取通话详情
    pub fn get_call_detail(call_id: &str) -> AppResult<Call> {
        let calls = CALLS.lock().unwrap();
        calls
            .get(call_id)
            .cloned()
            .ok_or_else(|| AppError::NotFoundError("通话不存在".to_string()))
    }

    // 获取注册列表
    pub fn get_registers() -> Vec<SipRegister> {
        let registers = REGISTERS.lock().unwrap();
        registers.values().cloned().collect()
    }

    // 创建SIP注册
    pub fn create_register(
        username: String,
        domain: String,
        password: String,
        sip_server: String,
        port: u16,
    ) -> AppResult<SipRegister> {
        let mut registers = REGISTERS.lock().unwrap();
        
        let register = SipRegister {
            id: Uuid::new_v4().to_string(),
            username,
            domain,
            password,
            status: RegisterStatus::Unregistered,
            register_time: None,
            expire_time: None,
            last_heartbeat: None,
            sip_server,
            port,
        };

        registers.insert(register.id.clone(), register.clone());
        Ok(register)
    }

    // 执行SIP注册
    pub fn perform_register(register_id: &str) -> AppResult<()> {
        let mut registers = REGISTERS.lock().unwrap();
        
        if let Some(register) = registers.get_mut(register_id) {
            register.status = RegisterStatus::Registered;
            register.register_time = Some(Utc::now());
            register.expire_time = Some(Utc::now() + chrono::Duration::hours(24));
            register.last_heartbeat = Some(Utc::now());
            Ok(())
        } else {
            Err(AppError::NotFoundError("注册记录不存在".to_string()))
        }
    }

    // 注销SIP
    pub fn unregister_sip(register_id: &str) -> AppResult<()> {
        let mut registers = REGISTERS.lock().unwrap();
        
        if let Some(register) = registers.get_mut(register_id) {
            register.status = RegisterStatus::Unregistered;
            register.register_time = None;
            register.expire_time = None;
            register.last_heartbeat = None;
            Ok(())
        } else {
            Err(AppError::NotFoundError("注册记录不存在".to_string()))
        }
    }

    // 更新心跳
    pub fn update_heartbeat(register_id: &str) -> AppResult<()> {
        let mut registers = REGISTERS.lock().unwrap();
        
        if let Some(register) = registers.get_mut(register_id) {
            register.last_heartbeat = Some(Utc::now());
            Ok(())
        } else {
            Err(AppError::NotFoundError("注册记录不存在".to_string()))
        }
    }

    // 检查过期注册
    pub fn check_expired_registrations() -> Vec<String> {
        let mut registers = REGISTERS.lock().unwrap();
        let mut expired_ids = Vec::new();
        
        for (id, register) in registers.iter_mut() {
            if let Some(expire_time) = register.expire_time {
                if Utc::now() > expire_time {
                    register.status = RegisterStatus::Expired;
                    expired_ids.push(id.clone());
                }
            }
        }
        
        expired_ids
    }

    // 获取活跃通话数量
    pub fn get_active_calls_count() -> i64 {
        let calls = CALLS.lock().unwrap();
        calls
            .values()
            .filter(|call| matches!(call.status, CallStatus::Active))
            .count() as i64
    }

    // 获取已注册用户数量
    pub fn get_registered_users_count() -> i64 {
        let registers = REGISTERS.lock().unwrap();
        registers
            .values()
            .filter(|reg| matches!(reg.status, RegisterStatus::Registered))
            .count() as i64
    }

    // 模拟SIP服务器连接测试
    pub fn test_sip_server_connection(sip_server: &str, port: u16) -> AppResult<bool> {
        // 这里应该实现真实的SIP服务器连接测试
        // 目前返回模拟结果
        Ok(true)
    }

    // 获取通话统计
    pub fn get_call_statistics() -> HashMap<String, i64> {
        let calls = CALLS.lock().unwrap();
        let mut stats = HashMap::new();
        
        let total_calls = calls.len() as i64;
        let active_calls = calls
            .values()
            .filter(|call| matches!(call.status, CallStatus::Active))
            .count() as i64;
        let ended_calls = calls
            .values()
            .filter(|call| matches!(call.status, CallStatus::Ended))
            .count() as i64;
        let failed_calls = calls
            .values()
            .filter(|call| matches!(call.status, CallStatus::Failed))
            .count() as i64;

        stats.insert("total".to_string(), total_calls);
        stats.insert("active".to_string(), active_calls);
        stats.insert("ended".to_string(), ended_calls);
        stats.insert("failed".to_string(), failed_calls);

        stats
    }
}
